package main

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"iot-base/devc/common/loader"
	"math"
	"strconv"
)

func ByteTogps(bytearr []byte, param loader.Param) interface{} {
	if len(bytearr) < 10 {
		fmt.Println("gps length is err!", bytearr)
		return nil
	}
	tmp := hex.EncodeToString(bytearr)
	return fmt.Sprintf("维度:%s度%s.%s分 经度:%s度%s.%s分", tmp[:2], tmp[2:4], tmp[4:9], tmp[9:11], tmp[11:13], tmp[13:18])
}

//取高字节位int
func ByteToHInt8(bytearr []byte, param loader.Param) interface{} {
	var intres int8
	intres = int8(bytearr[0])
	var res float64
	if param.Additive != nil {
		res = float64(intres) + float64(*param.Additive)
	} else {
		res = float64(intres)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(int8(res))

}

//取高字节位int
func ByteToLInt8(bytearr []byte, param loader.Param) interface{} {
	var intres int8
	intres = int8(bytearr[1])
	var res float64
	if param.Additive != nil {
		res = float64(intres) + float64(*param.Additive)
	} else {
		res = float64(intres)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(int16(res))

}

//高低字节转换
func ByteSwap(bytes []byte) []byte {
	var res []byte
	for i := 0; i < len(bytes); i += 2 {
		res = append(res, bytes[i+1])
		res = append(res, bytes[i])
	}
	return res
}

//bool解析
func ByteToBool(bytearr []byte, param loader.Param) interface{} {
	tmpby := make([]byte, len(bytearr))
	copy(tmpby, bytearr)
	bytesBuffer := bytes.NewBuffer(tmpby)
	//fmt.Println("inbool:",bytesBuffer.Bytes())
	if len(bytearr) == 2 {
		var tmp uint16
		if param.Endian {
			err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
			if err != nil {
				fmt.Println("parse bool err:", err)
			}
		} else {
			err := binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
			if err != nil {
				fmt.Println("parse bool err:", err)
			}
		}
		err := binary.Write(bytesBuffer, binary.LittleEndian, &tmp)
		if err != nil {
			fmt.Println("write littleendian data err:", err)
		}
	} else if len(bytearr) == 1 {
		var tmp uint8
		if param.Endian {
			err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
			if err != nil {
				fmt.Println("parse bool err:", err)
			}
		} else {
			err := binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
			if err != nil {
				fmt.Println("parse bool err:", err)
			}
		}
		err := binary.Write(bytesBuffer, binary.LittleEndian, &tmp)
		if err != nil {
			fmt.Println("write littleendian data err:", err)
		}
	}
	tmpby = bytesBuffer.Bytes()
	//fmt.Println("outbool:",bytesBuffer.Bytes())
	//if param.Number != nil{
	//	fmt.Println("number:",*param.Number)
	//}
	if param.Number != nil && len(tmpby) != 0 {
		if int(*param.Number) > 7 && len(tmpby) > 1 {
			//fmt.Println(fmt.Sprintf("%d",(tmpby[1] >> int(*param.Number-8)) & 0x1))
			return fmt.Sprintf("%d", (tmpby[1]>>int(*param.Number-8))&0x1)
		}
		//fmt.Println(fmt.Sprintf("%d",(tmpby[0] >> int(*param.Number)) & 0x1))
		return fmt.Sprintf("%d", (tmpby[0]>>int(*param.Number))&0x1)
	} else if param.Number == nil {
		//fmt.Println(fmt.Sprintf("%d",tmpby[0] & 0x1))
		return fmt.Sprintf("%d", tmpby[0]&0x1)
	} else {
		return nil
	}
}

func BoolToByte(indt string, param loader.Param) []byte {
	switch indt {
	case "0":
		return []byte{0x00, 0x00}
	case "1":
		return []byte{0xff, 0x00}
	default:
		return nil
	}
}

//float32解析
func Float32ToByte(indt string, param loader.Param) []byte {
	floattmp, err := strconv.ParseFloat(indt, 32)
	if err != nil {
		fmt.Println("convert float32 err!")
	}
	bits := math.Float32bits(float32(floattmp))
	bytes := make([]byte, 4)
	if param.Endian {
		binary.BigEndian.PutUint32(bytes, bits)
	} else {
		binary.LittleEndian.PutUint32(bytes, bits)
	}
	return bytes
}

func ByteToFloat32(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	var bits uint32
	if param.Endian {
		bits = binary.BigEndian.Uint32(bytearr)
	} else {
		bits = binary.LittleEndian.Uint32(bytearr)
	}
	tmp := math.Float32frombits(bits)
	if param.Additive != nil {
		tmp = tmp + float32(*param.Additive)
	}
	if param.Number != nil {
		tmp = tmp * float32(*param.Number)
	}
	return float64(tmp)
}

//double解析
func DoubleToByte(indt string, param loader.Param) []byte {
	doubletmp, err := strconv.ParseFloat(indt, 32)
	if err != nil {
		fmt.Println("convert double err!")
	}
	bits := math.Float64bits(doubletmp)
	bytes := make([]byte, 8)
	if param.Endian {
		binary.BigEndian.PutUint64(bytes, bits)
	} else {
		binary.LittleEndian.PutUint64(bytes, bits)
	}
	return bytes
}

func ByteToDouble(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	var bits uint64
	if param.Endian {
		bits = binary.BigEndian.Uint64(bytearr)
	} else {
		bits = binary.LittleEndian.Uint64(bytearr)
	}
	tmp := math.Float64frombits(bits)
	if param.Additive != nil {
		tmp = tmp + float64(*param.Additive)
	}
	if param.Number != nil {
		tmp = tmp * float64(*param.Number)
	}
	return tmp
}

//int16解析
func Int16ToByte(indt string, param loader.Param) []byte {
	int16tmp, err := strconv.ParseInt(indt, 10, 16)
	if err != nil {
		fmt.Println("convert int16 err!")
	}
	tmp := int16(int16tmp)
	var bytesBuffer *bytes.Buffer
	if param.Number != nil {
		tmp = tmp * int16(*param.Number)
	}
	fmt.Println("tmp:", tmp)
	if param.Endian {
		bytesBuffer = bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.BigEndian, &tmp)
	} else {
		bytesBuffer = bytes.NewBuffer([]byte{})
		//bytesBuffer := bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.LittleEndian, &tmp)
	}
	fmt.Println("byte:", bytesBuffer.Bytes())
	return bytesBuffer.Bytes()
}

func ByteToInt16(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	bytesBuffer := bytes.NewBuffer(bytearr)
	var tmp int16
	if param.Endian {
		err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
		if err != nil {
			fmt.Println("parse int16 err:", err)
		}
	} else {
		err := binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
		if err != nil {
			fmt.Println("parse int16 err:", err)
		}
	}
	var res float64
	if param.Additive != nil {
		res = float64(tmp) + float64(*param.Additive)
	} else {
		res = float64(tmp)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(int16(res))
}

//int32解析
func Int32ToByte(indt string, param loader.Param) []byte {
	int32tmp, err := strconv.ParseInt(indt, 10, 32)
	if err != nil {
		fmt.Println("convert int16 err!")
	}
	tmp := int32(int32tmp)
	var bytesBuffer *bytes.Buffer
	if param.Endian {
		bytesBuffer := bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.BigEndian, &tmp)
	} else {
		bytesBuffer := bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.LittleEndian, &tmp)
	}
	return bytesBuffer.Bytes()
}

func ByteToInt32(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	bytesBuffer := bytes.NewBuffer(bytearr)
	var tmp int32
	if param.Endian {
		err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
		if err != nil {
			fmt.Println("parse int32 err:", err)
		}
	} else {
		err := binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
		if err != nil {
			fmt.Println("parse int32 err:", err)
		}
	}
	var res float64
	if param.Additive != nil {
		res = float64(tmp) + float64(*param.Additive)
	} else {
		res = float64(tmp)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(int32(res))
}

//int64解析
func Int64ToByte(indt string, param loader.Param) []byte {
	int64tmp, err := strconv.ParseInt(indt, 10, 64)
	if err != nil {
		fmt.Println("convert int16 err!")
	}
	tmp := int64tmp
	var bytesBuffer *bytes.Buffer
	if param.Endian {
		bytesBuffer := bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.BigEndian, &tmp)
	} else {
		bytesBuffer := bytes.NewBuffer([]byte{})
		binary.Write(bytesBuffer, binary.LittleEndian, &tmp)
	}
	return bytesBuffer.Bytes()
}

func ByteToInt64(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	bytesBuffer := bytes.NewBuffer(bytearr)
	var tmp int64
	if param.Endian {
		err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
		if err != nil {
			fmt.Println("parse int32 err:", err)
		}
	} else {
		err := binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
		if err != nil {
			fmt.Println("parse int32 err:", err)
		}
	}
	var res float64
	if param.Additive != nil {
		res = float64(tmp) + float64(*param.Additive)
	} else {
		res = float64(tmp)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(int64(res))
}

//uint32解析
func Uint16ToByte(indt string, param loader.Param) []byte {
	uint16tmp, err := strconv.ParseUint(indt, 10, 16)
	if err != nil {
		fmt.Println("convert int16 err!")
	}
	bytes := make([]byte, 2)
	if param.Endian {
		binary.BigEndian.PutUint16(bytes, uint16(uint16tmp))
	} else {
		binary.LittleEndian.PutUint16(bytes, uint16(uint16tmp))
	}
	return bytes
}

func ByteToUint16(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	var bits uint16
	if param.Endian {
		bits = binary.BigEndian.Uint16(bytearr)
	} else {
		bits = binary.LittleEndian.Uint16(bytearr)
	}
	var res float64
	if param.Additive != nil {
		res = float64(bits) + float64(*param.Additive)
	} else {
		res = float64(bits)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(uint16(res))
}

//uint32解析
func Uint32ToByte(indt string, param loader.Param) []byte {
	uint32tmp, err := strconv.ParseUint(indt, 10, 16)
	if err != nil {
		fmt.Println("convert int16 err!")
	}
	bytes := make([]byte, 4)
	if param.Endian {
		binary.BigEndian.PutUint32(bytes, uint32(uint32tmp))
	} else {
		binary.LittleEndian.PutUint32(bytes, uint32(uint32tmp))
	}
	return bytes
}

func ByteToUint32(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	var bits uint32
	if param.Endian {
		bits = binary.BigEndian.Uint32(bytearr)
	} else {
		bits = binary.LittleEndian.Uint32(bytearr)
	}
	var res float64
	if param.Additive != nil {
		res = float64(bits) + float64(*param.Additive)
	} else {
		res = float64(bits)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(uint32(res))
}

//uint64解析
func Uint64ToByte(indt string, param loader.Param) []byte {
	uint64tmp, err := strconv.ParseUint(indt, 10, 64)
	if err != nil {
		fmt.Println("string return err!")
		return nil
	}
	bytes := make([]byte, 8)
	if param.Endian {
		binary.BigEndian.PutUint64(bytes, uint64tmp)
	} else {
		binary.LittleEndian.PutUint64(bytes, uint64tmp)
	}
	return bytes
}

func ByteToUint64(bytearr []byte, param loader.Param) interface{} {
	if param.Swap {
		bytearr = ByteSwap(bytearr)
	}
	var bits uint64
	if param.Endian {
		bits = binary.BigEndian.Uint64(bytearr)
	} else {
		bits = binary.LittleEndian.Uint64(bytearr)
	}
	var res float64
	if param.Additive != nil {
		res = float64(bits) + float64(*param.Additive)
	} else {
		res = float64(bits)
	}
	if param.Number != nil {
		res = res * float64(*param.Number)
		return res
	}
	return fmt.Sprint(uint64(res))
}

func ByteToString(bytearr []byte, param loader.Param) interface{} {
	return string(bytearr)
}

func StringToByte(indt string, param loader.Param) []byte {
	return []byte(indt)
}
